package com.jt.interceptor;

import com.jt.utils.Page;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.PreparedStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;

import java.sql.*;
import java.util.Properties;


@Intercepts(@Signature(
        type= StatementHandler.class,
        method = "prepare",
        args={Connection.class,Integer.class}
))
public class PageInterceptor implements Interceptor {

    private static ThreadLocal<Page> threadLocal;

    public static void setPage(ThreadLocal<Page> threadLocal){
        PageInterceptor.threadLocal = threadLocal;
    }

    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        MetaObject metaObject1 = SystemMetaObject.forObject(invocation.getTarget());

        // h 是拿插件的  target是拿最后的目标对象的statamenthandler
        while(metaObject1.hasGetter("h")){
            //把插件拿出来,继续转换成metaObject对象继续拿
            metaObject1 = SystemMetaObject.forObject( metaObject1.getValue("h"));
        }

        StatementHandler statementHandler = (StatementHandler)metaObject1.getValue("target");
        metaObject1 = SystemMetaObject.forObject(statementHandler);


        System.out.println("执行的sql语句"+metaObject1.getValue("delegate.boundSql.sql"));

        String sql = metaObject1.getValue("delegate.boundSql.sql").toString().toLowerCase().trim();

        /**
         * 执行查询才会存在分页， 如果你开启了分页我才给你分页，分页通过controller里面传的page来控制
         */
        if(!sql.startsWith("select") || threadLocal == null) return invocation.proceed();

        // select　＊　from　　user where name like ? limit sql语句中本身就含有limit
        if(sql.indexOf("limit")!=-1)return invocation.proceed();

        // select * from user where xxx xxx  如果能到这里，sql语句中一定不会含有 limit  insert  update


        // 分页
        System.out.println("jie qu dao de :"+sql.substring(sql.indexOf("from")));

        String sql2 = "select count(1) " + sql.substring(sql.indexOf("from"));
        //重启一条查询
        Connection connection = (Connection)invocation.getArgs()[0];
        PreparedStatement preparedStatement = connection.prepareStatement(sql2);

        //参数赋值

        ParameterHandler parameterHandler =(ParameterHandler) metaObject1.getValue("delegate.parameterHandler");
        System.out.println("ParameterHandler:"+parameterHandler);
        parameterHandler.setParameters(preparedStatement);
        //执行sql语句
        ResultSet resultSet = preparedStatement.executeQuery();
        int count = 0;
        if(resultSet.next()){
            count = resultSet.getInt(1);
        }
        Page page = threadLocal.get();
        page.setCount(count);

        //拼接分页语句 limit
        metaObject1.setValue("delegate.boundSql.sql", sql + " limit ?,? ");

        // select * from  user where name like ? or age =?  limit ?,?
        PreparedStatement statement = (PreparedStatement)invocation.proceed();
        int paramCount= statement.getParameterMetaData().getParameterCount();
        statement.setInt(paramCount-1,(page.getCurrentPage()-1)*page.getPageSize());
        statement.setInt(paramCount,page.getPageSize());
        System.out.println("canshu："+paramCount);
        //mybatis提供的获取属性的一个类
        //MetaObject metaObject = SystemMetaObject.forObject(target);

        //Object value = metaObject.getValue("delegate.boundSql.sql").toString();
        //System.out.println("通过metaObject:"+value);



        page = null;

        return  statement;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target,this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
